Socket
Socket
Sign inDemoInstall

request-compose

Package Overview
Dependencies
0
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    request-compose

Composable HTTP Client


Version published
Weekly downloads
140K
decreased by-22.93%
Maintainers
1
Install size
51.9 kB
Created
Weekly downloads
 

Changelog

Source

v2.1.6 (2022/12/22)

  • Change: Update deps and docs

Readme

Source

request-compose

npm-version test-ci-img test-cov-img snyk-vulnerabilities

Composable HTTP Client

var compose = require('request-compose')
var Request = compose.Request
var Response = compose.Response

;(async () => {
  try {
    var {res, body} = await compose(
      Request.defaults({headers: {'user-agent': 'request-compose'}}),
      Request.url('https://api.github.com/users/simov'),
      Request.send(),
      Response.buffer(),
      Response.string(),
      Response.parse(),
    )()
    console.log(res.statusCode, res.statusMessage)
    console.log(res.headers['x-ratelimit-remaining'])
    console.log(body)
  }
  catch (err) {
    console.error(err)
  }
})()

Goals

  • No dependencies
  • No abstraction
  • No state

Table of Contents

Compose

In computer science, function composition (not to be confused with object composition) is an act or mechanism to combine simple functions to build more complicated ones. Like the usual composition of functions in mathematics, the result of each function is passed as the argument of the next, and the result of the last one is the result of the whole.

var compose = require('request-compose')

Accepts a list of functions to execute and returns a Promise:

var doit = compose(
  (a) => a + 2,
  (a) => a * 2,
)

Then we can call it:

var result = await doit(5) // 14

A more practical example however would be to compose our own HTTP client:

var compose = require('request-compose')
var https = require('https')

var request = compose(
  (options) => {
    options.headers = options.headers || {}
    options.headers['user-agent'] = 'request-compose'
    return options
  },
  (options) => new Promise((resolve, reject) => {
    https.request(options)
      .on('response', resolve)
      .on('error', reject)
      .end()
  }),
  async (res) => await new Promise((resolve, reject) => {
    var body = ''
    res
      .on('data', (chunk) => body += chunk)
      .on('end', () => resolve({res, body}))
      .on('error', reject)
  }),
  ({res, body}) => ({res, body: JSON.parse(body)}),
)

Then we can use it like this:

;(async () => {
  try {
    var {res, body} = await request({
      protocol: 'https:',
      hostname: 'api.github.com',
      path: '/users/simov',
    })
    console.log(res.statusCode, res.statusMessage)
    console.log(res.headers['x-ratelimit-remaining'])
    console.log(body)
  }
  catch (err) {
    console.error(err)
  }
})()

Bundled Middlewares

request-compose comes with a bunch of pre-defined middlewares for transforming the request and the response:

var compose = require('request-compose')
var Request = compose.Request
var Response = compose.Response

We can use these middlewares to compose our own HTTP client:

;(async () => {
  try {
    var {res, body} = await compose(
      Request.defaults({headers: {'user-agent': 'request-compose'}}),
      Request.url('https://api.github.com/users/simov'),
      Request.send(),
      Response.buffer(),
      Response.string(),
      Response.parse(),
    )()
    console.log(res.statusCode, res.statusMessage)
    console.log(res.headers['x-ratelimit-remaining'])
    console.log(body)
  }
  catch (err) {
    console.error(err)
  }
})()
TypeMiddlewareInputArgumentsReturns
Requestdefaults{input}{input}{options}
Requesturl, proxy, qs, cookiesee options{options}{options}
Requestform, json, multipart, bodysee options{options}{options, body}
Requestauth, oauthsee options{options, body}{options, body}
Requestlength-{options, body}{options, body}
Requestsend-{options, body}{options, res}
Responsebuffer-{options, res}{options, res, body}
Responsegzip-{options, res, body, raw}{options, res, body, raw}
Responsestringsee options{options, res, body, raw}{options, res, body, raw}
Responseparse, status-{options, res, body, raw}{options, res, body, raw}
Responseredirect(input, client){options, res, body, raw}new composition

Opinionated Client

request-compose comes with opinionated HTTP client that is composed of the above middlewares.

There are 3 types of composition available based on the returned data type:

client

var request = require('request-compose').client
var {res, body} = await request({options})

The client composition does the following:

  • buffers the response body
  • decompresses gzip and deflate encoded bodies with valid content-encoding header
  • converts the response body to string using utf8 encoding by default
  • tries to parse JSON and querystring encoded bodies with valid content-type header

Returns either String or Object.

buffer

var request = require('request-compose').buffer
var {res, body} = await request({options})

The buffer composition does the following:

  • buffers the response body
  • decompresses gzip and deflate encoded bodies with valid content-encoding header

Returns Buffer.

stream

var request = require('request-compose').stream
var {res} = await request({options})

The stream composition returns the response Stream.

options

The above compositions accept any of the Node's http.request and https.request options:

var {res, body} = await request({
  method: 'GET',
  url: 'https://api.github.com/users/simov',
  headers: {
    'user-agent': 'request-compose'
  }
})

Additionally the following options are available:

OptionTypeDescription
url'string' url objectURL (encoding - see below)
proxy'string' url objectProxy URL
qs{object} 'string'URL querystring (encoding - see below)
form{object} 'string'application/x-www-form-urlencoded request body (encoding - see below)
json{object} 'string'JSON encoded request body
multipart{object} [array]multipart request body using request-multipart, see examples
body'string' Buffer Streamrequest body
auth{user, pass}Basic authorization
oauth{object}OAuth 1.0a authorization using request-oauth, see examples
encoding'string'response body encoding (default: 'utf8')
cookie{object}cookie store using request-cookie, see examples
redirect{object}see below

Querystring set in the url, and/or in qs and/or in form as 'string' is left untouched, meaning that the proper encoding is left to the user.

When qs and/or form is {object} the querystring is encoded using the Node's querystring module which mirrors the global encodeURIComponent method. Additionally all reserved characters according to RFC3986 are encoded as well. Full list of all reserved characters that are being encoded can be found here.

redirect
OptionDefaultDescription
max3maximum number of redirects to follow
allfalsefollow non-GET HTTP 3xx responses as redirects
methodtruefollow original HTTP method, otherwise convert all redirects to GET
authtruekeep Authorization header when changing hostnames
refererfalseadd Referer header

extend

Extend or override any of the bundled request and response middlewares:

var request = require('request-compose').extend({
  Request: {
    oauth: require('request-oauth'),
    multipart: require('request-multipart'),
    cookie: require('request-cookie').Request
  },
  Response: {cookie: require('request-cookie').Response},
}).client

Errors

Non 200/300 responses are thrown as Error object with the following properties:

  • message - status code + status message
  • res - the response object
  • body - the parsed response body
  • raw - the raw response body

Debug Logs

Fancy request-logs:

npm i --save-dev request-logs

Pick any of the following debug options:

DEBUG=req,res,body,json,nocolor node app.js

Examples

TopicExample
Basics
Types of lambda functionsGet GitHub user profile
Bundled middlewaresGet GitHub user profile
Wrap it up and extend itGet GitHub user profile
Compositions
ClientGet GitHub user profile
BufferDecoding response body using iconv-lite
StreamStream Tweets
External Middlewares
OAuth (request-oauth)Get Twitter User Profile
Multipart (request-multipart)Upload photo to Twitter
Cookie (request-cookie)Login to Wallhaven.cc
Stream
Stream request bodyUpload file to Dropbox
HTTP streamUpload image from Dropbox to Slack
HTTP streamCopy file from Dropbox to GDrive
Misc
Gzip decompressionRequest Gzip compressed body
HTTPS proxyTunnel Agent
HTTPS proxyProxy Agent
Override bundled middleware - per compose instanceOverride the qs middleware
Override bundled middleware - process-wideOverride the form and the parse middlewares to use the qs module
Pipeline
App pipelineSlack Weather Status
App pipelineSimultaneously search for repos in GitHub, GitLab and BitBucket
Modules
Google Chrome Web Store HTTP Clientchrome-webstore
REST API Client Librarypurest

Keywords

FAQs

Last updated on 22 Dec 2022

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc